package cn.lili.modules.promotion.serviceimpl;

import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.AuthUser;
import cn.lili.common.utils.BlindboxCodeUtil;
import cn.lili.common.utils.DateUtil;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.vo.PageVO;
import cn.lili.modules.payment.entity.dos.UserWithdrawApply;
import cn.lili.modules.promotion.entity.dos.BlindboxPrizePaper;
import cn.lili.modules.promotion.entity.dos.BlindboxPrizeRecord;
import cn.lili.modules.promotion.entity.dos.BlindboxRule;
import cn.lili.modules.promotion.entity.dto.search.BlindboxPrizepaperSearchParams;
import cn.lili.modules.promotion.entity.vos.BlindboxVO;
import cn.lili.modules.promotion.manage.BlindboxCountManage;
import cn.lili.modules.promotion.manage.BlindboxPrizePaperManage;
import cn.lili.modules.promotion.mapper.BlindboxPrizePaperMapper;
import cn.lili.modules.promotion.mapper.BlindboxPrizeRecordMapper;
import cn.lili.modules.promotion.service.BlindboxPrizePaperService;
import cn.lili.modules.promotion.service.BlindboxPrizeRecordService;
import cn.lili.modules.promotion.service.BlindboxRelService;
import cn.lili.modules.promotion.service.BlindboxRuleService;
import cn.lili.mybatis.util.PageUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * 盲盒奖卷 业务实现
 *
 * @author xiangqian
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class BlindboxPrizePaperServiceImpl extends ServiceImpl<BlindboxPrizePaperMapper, BlindboxPrizePaper> implements BlindboxPrizePaperService {

    @Resource
    private BlindboxPrizePaperManage blindboxPrizePaperManage;
    @Resource
    private BlindboxPrizeRecordService blindboxPrizeRecordService;
    @Resource
    private BlindboxCodeUtil blindboxCodeUtil;

    @Override
    public Page<BlindboxPrizePaper> getPage(BlindboxPrizePaper queryParam, PageVO page) {
        LambdaQueryWrapper<BlindboxPrizePaper> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotEmpty(queryParam.getGoodsId()),BlindboxPrizePaper::getGoodsId,queryParam.getGoodsId());
        queryWrapper.eq(StringUtils.isNotEmpty(queryParam.getCode()),BlindboxPrizePaper::getCode,queryParam.getCode());
        return this.baseMapper.selectPage(PageUtil.initPage(page), queryWrapper);
    }

    /**
     * 根据商品id查询盲盒活动
     *
     * @param currentUser 用户
     * @param goodsId     商品ID
     */
    @Override
    public BlindboxVO getBlindbox(AuthUser currentUser, String goodsId) {
        //查询盲盒规则
        BlindboxRule blindboxRule = blindboxPrizePaperManage.getBlindboxRule(goodsId);
        //查询盲盒子统计信息-已抽奖卷
        Integer prizeNumber = blindboxPrizePaperManage.getPrizeNumber(goodsId, blindboxRule.getRuleBuyNum());
        //根据商品ID查询开奖时间
        BlindboxPrizeRecord blindboxPrizeRecord = blindboxPrizeRecordService.getBlindboxPrizeRecord(goodsId);
        //查询我的奖卷
        List<BlindboxPrizePaper> blindboxPrizePaperList = getBlindboxPrizePaper(currentUser.getExtendId(), goodsId);
        //查询总计购买次数
        Integer myPrizeNumber = blindboxPrizePaperManage.getMyPrizeNumber(goodsId, currentUser.getExtendId());

        BlindboxVO blindboxVO = new BlindboxVO();
        //初始化已抽奖卷
        blindboxVO.initPrizeNumber(blindboxRule, prizeNumber, blindboxVO);
        blindboxVO.setPrizeTime(blindboxPrizeRecord!=null?blindboxPrizeRecord.getPrizeTime():null);
        //初始化我的奖卷
        blindboxVO.initPrizeCode(blindboxPrizePaperList, blindboxVO);
        //昵称
        blindboxVO.setNickName(currentUser.getNickName());
        // 购买次数（购买多少次算一次奖卷）
        blindboxVO.setRuleBuyNum(blindboxRule.getRuleBuyNum());
        // 我的购买次数
        blindboxVO.setMyRuleBuyNum(myPrizeNumber);

        //查询当前时间是否已经达到开奖时间，如果达到了则公开开奖结果
        if(blindboxVO.getPrizeTime()!=null && !blindboxPrizeRecord.getType()){
            long beginTime = DateUtil.getDateline();
            long endTime = DateUtil.getDateline(DateUtil.toString(blindboxVO.getPrizeTime()), DateUtil.STANDARD_FORMAT);
            if(endTime - beginTime <= 0){
                blindboxPrizeRecord.setType(Boolean.TRUE);
                blindboxPrizeRecordService.updateById(blindboxPrizeRecord);
            }
        }
        return blindboxVO;
    }

    /**
     * 根据商品ID加用户ID查询我的奖卷
     *
     * @param goodsId  商品ID
     * @param memberId 用户ID
     */
    @Override
    public List<BlindboxPrizePaper> getBlindboxPrizePaper(String memberId, String goodsId) {
        LambdaQueryWrapper<BlindboxPrizePaper> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(StringUtils.isNotEmpty(memberId),BlindboxPrizePaper::getUserId, memberId);
        lambdaQueryWrapper.eq(BlindboxPrizePaper::getGoodsId, goodsId);
        lambdaQueryWrapper.eq(BlindboxPrizePaper::getDeleteFlag, false);
        lambdaQueryWrapper.orderByDesc(BlindboxPrizePaper::getCreateTime);
        List<BlindboxPrizePaper> list = this.baseMapper.selectList(lambdaQueryWrapper);
        return list;
    }

    @Override
    public List<BlindboxPrizePaper> getPrizepaper(AuthUser currentUser, BlindboxPrizepaperSearchParams blindboxPrizepaperSearchParams) {
        LambdaQueryWrapper<BlindboxPrizePaper> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(BlindboxPrizePaper::getUserId, currentUser.getExtendId());
        lambdaQueryWrapper.eq(StringUtils.isNotEmpty(blindboxPrizepaperSearchParams.getGoodsId()), BlindboxPrizePaper::getGoodsId, blindboxPrizepaperSearchParams.getGoodsId());
        lambdaQueryWrapper.eq(blindboxPrizepaperSearchParams.getIsRead() != null, BlindboxPrizePaper::getIsRead, blindboxPrizepaperSearchParams.getIsRead());
        lambdaQueryWrapper.eq(BlindboxPrizePaper::getDeleteFlag, false);
        return this.baseMapper.selectList(lambdaQueryWrapper);
    }

    @Override
    public boolean updatePrizepaperRead(AuthUser currentUser, List<String> codes) {
        if(codes == null || codes.size()<1){
            return false;
        }

        LambdaUpdateWrapper<BlindboxPrizePaper> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(BlindboxPrizePaper::getUserId, currentUser.getExtendId())
                .in(BlindboxPrizePaper::getCode, codes)
                .set(BlindboxPrizePaper::getIsRead, true);
        this.baseMapper.update(null, updateWrapper);
        return true;
    }

    @Override
    public synchronized boolean insertPrizepaperRead(String userId, String goodsId, BlindboxRule blindboxRule) {
        BlindboxPrizePaper blindboxPrizePaper = new BlindboxPrizePaper();
        blindboxPrizePaper.setUserId(userId);
        String code = blindboxCodeUtil.generateCouponsOne(goodsId,blindboxRule.getId(),blindboxRule.getRuleNum());
        //查询奖卷是否重复
        LambdaQueryWrapper<BlindboxPrizePaper> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(BlindboxPrizePaper::getUserId,userId);
        lambdaQueryWrapper.eq(BlindboxPrizePaper::getGoodsId,goodsId);
        lambdaQueryWrapper.eq(BlindboxPrizePaper::getCode,code);
        lambdaQueryWrapper.last("limit 1");
        BlindboxPrizePaper temp = this.baseMapper.selectOne(lambdaQueryWrapper);
        if(temp != null){
            log.info("奖卷重复");
        }else{
            blindboxPrizePaper.setCode(code);
            blindboxPrizePaper.setGoodsId(goodsId);
            blindboxPrizePaper.setIsRead(false);
            this.baseMapper.insert(blindboxPrizePaper);
        }
        return true;
    }

    @Override
    public BlindboxPrizePaper getPrizepaperByCode(String code) {
        LambdaQueryWrapper<BlindboxPrizePaper> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(BlindboxPrizePaper::getCode, code);
        lambdaQueryWrapper.eq(BlindboxPrizePaper::getDeleteFlag, false);
        return this.baseMapper.selectOne(lambdaQueryWrapper);
    }
}